import asyncio
import logging
from typing import Any, Optional, Dict
import httpx
import json
import lark_oapi as lark
from lark_oapi.api.contact.v3 import *
from lark_oapi.api.im.v1 import *

class FeishuSDK:
    """
    飞书发送消息异步 SDK 封装（仅支持 text 类型）。
    支持自动重试和指数退避。

    Args:
        config (dict): 配置字典，例如：
            {
                "base_url": "https://open.feishu.cn/open-apis/im/v1/messages",
                "access_token": "your_token",
                "max_retries": 3,
                "retry_delay": 1,
                "backoff_factor": 2,
                "proxy": None,
            }
        logger (optional): 自定义日志记录器
    """

    def __init__(self, config: dict, logger=None):
        self.app_id = config.get("app_id", "")
        self.app_secret = config.get("app_secret","")
        self.base_url = config.get("base_url", "").rstrip('/')
        self.proxy = config.get("proxy", None)
        self.logger = logger or logging.getLogger(__name__)
        self.max_retries = config.get("max_retries", 3)
        self.retry_delay = config.get("retry_delay", 1)
        self.backoff_factor = config.get("backoff_factor", 2)
        self._client =lark.Client.builder().app_id(self.app_id).app_secret(self.app_secret).log_level(lark.LogLevel.DEBUG).build()

    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self._client.aclose()

    def _should_retry(self, response: httpx.Response = None, exception: Exception = None) -> bool:
        if exception is not None:
            return True
        if response is not None and response.status_code in (429, 500, 502, 503, 504):
            return True
        return False

    async def query_openid(self,tel_number:str):
        # 构造请求对象
        request: BatchGetIdUserRequest = BatchGetIdUserRequest.builder() \
            .user_id_type("open_id") \
            .request_body(BatchGetIdUserRequestBody.builder()
                .mobiles([tel_number])
                .include_resigned(True)
                .build()).build()

        # 发起请求
        response: BatchGetIdUserResponse = self._client.contact.v3.user.batch_get_id(request)
        
        # 处理失败返回
        if not response.success():
            lark.logger.error(
                f"client.contact.v3.user.batch_get_id failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
            return None

        # 处理业务结果
        lark.logger.info(lark.JSON.marshal(response.data, indent=4))
            # 提取 user_id（假设只查一个手机号）
        user_list = response.data.user_list
        if not user_list:
            lark.logger.warning("user_list is empty.")
            return None

        user_id = user_list[0].user_id
        lark.logger.info(f"Found user_id: {user_id}")

        return user_id

    async def send_message(self,open_id:str,content:str):
        request: CreateMessageRequest = CreateMessageRequest.builder() \
        .receive_id_type("open_id") \
        .request_body(CreateMessageRequestBody.builder()
            .receive_id(f"{open_id}")
            .msg_type("text")
            .content(json.dumps({"text": content}))
            .build()) \
        .build()

        # 发起请求
        response: CreateMessageResponse = self._client.im.v1.message.create(request)

        # 处理失败返回
        if not response.success():
            lark.logger.error(
                f"client.im.v1.message.create failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
            return

        # 处理业务结果
        lark.logger.info(lark.JSON.marshal(response.data, indent=4))
        return True